﻿#include <QApplication>
#include <QDebug>
#include <QDragLeaveEvent>
#include <QDragMoveEvent>
#include <QLabel>
#include <QMainWindow>
#include <QMimeData>
#include <QSplitter>
#include <QTreeWidget>
#include <QVBoxLayout>
#include <QWidget>

#include "qcustomplot.h"

class PlotWidget : public QCustomPlot {
  Q_OBJECT
 public:
  PlotWidget(QWidget* parent = nullptr) : QCustomPlot(parent) {
    setAcceptDrops(true);
    m_currentAreaIndex = -1;

    // 清除默认的坐标轴区域
    plotLayout()->clear();

    // 创建3个垂直排列的坐标轴区域
    for (int i = 0; i < 3; ++i) {
      // 为每个区域添加标题
      QCPTextElement* title = 
          new QCPTextElement(this, QString("Plot Area %1").arg(i + 1));
      plotLayout()->addElement(i * 2, 0, title);
      
      // 创建坐标轴区域
      QCPAxisRect* axisRect = new QCPAxisRect(this);
      m_axisRects.append(axisRect);
      
      // 添加坐标轴区域到布局
      plotLayout()->addElement(i * 2 + 1, 0, axisRect);
      
      // 设置每个行的拉伸系数，使3个绘图区域平均分布
      plotLayout()->setRowStretchFactor(i * 2 + 1, 1);
    }

    // 创建透明层
    overlay = new QWidget(this);
    overlay->setStyleSheet(
        "background-color: rgba(0, 150, 255, 60); border: 2px dashed rgba(0, "
        "150, 255, 150); border-radius: 5px;");
    // 默认隐藏
    overlay->hide();  

    // 添加标签显示在透明层上
    overlayLabel = new QLabel(overlay);
    overlayLabel->setText("释放添加曲线");
    overlayLabel->setStyleSheet("color: rgb(0, 100, 200); font-weight: bold;");
    overlayLabel->setAlignment(Qt::AlignCenter);

    // 创建布局管理器
    QVBoxLayout* overlayLayout = new QVBoxLayout(overlay);
    overlayLayout->addWidget(overlayLabel, 0, Qt::AlignCenter);
    overlayLayout->setContentsMargins(0, 0, 0, 0);
    overlay->setLayout(overlayLayout);
  }

  // 重写resizeEvent以确保overlay随窗口大小变化
  void resizeEvent(QResizeEvent* event) override {
    QCustomPlot::resizeEvent(event);
    updateOverlayPosition();
  }

 protected:
  void dragEnterEvent(QDragEnterEvent* event) override {
    if (event->mimeData()->hasText()) {
      // 更新透明层位置
      updateOverlayPosition(event->pos());
      overlay->show();
      event->acceptProposedAction();
    }
  }

  // 当拖拽离开时隐藏透明层
  void dragLeaveEvent(QDragLeaveEvent* event) override {
    overlay->hide();
    m_currentAreaIndex = -1;
    QCustomPlot::dragLeaveEvent(event);
  }

  // 当在区域内移动时更新透明层显示
  void dragMoveEvent(QDragMoveEvent* event) override {
    if (event->mimeData()->hasText()) {
      // 更新透明层位置
      updateOverlayPosition(event->pos());
      event->acceptProposedAction();
    }
  }

  void dropEvent(QDropEvent* event) override {
    QString itemText = event->mimeData()->text();

    // 隐藏透明层
    overlay->hide();

    // 确定当前拖放的区域
    int areaIndex = getAreaIndex(event->pos());
    if (areaIndex >= 0 && areaIndex < m_axisRects.size()) {
      qDebug() << "Dropped:" << itemText << "in plot area" << areaIndex + 1;

      // 获取当前区域
      QCPAxisRect* axisRect = m_axisRects[areaIndex];

      // 生成随机波形示例数据
      QVector<double> x(100), y(100);
      for (int i = 0; i < 100; ++i) {
        x[i] = i;
        // 给每条曲线略微偏移
        y[i] = qSin(i / 10.0 + graphCount() * 0.5) +
               (qrand() % 100) / 100.0;  
      }

      // 在当前区域新增一条曲线
      QCPGraph* g = addGraph(axisRect->axis(QCPAxis::atBottom),
                             axisRect->axis(QCPAxis::atLeft));
      g->setData(x, y);
      g->setName(itemText);

      // 设置不同的颜色区分多条曲线
      QPen pen;
      pen.setColor(QColor::fromHsv(graphCount() * 60 % 360, 200, 200));
      g->setPen(pen);

      // 自动缩放当前区域的坐标轴
      axisRect->axis(QCPAxis::atBottom)->rescale(true);
      axisRect->axis(QCPAxis::atLeft)->rescale(true);
      replot();
    }

    m_currentAreaIndex = -1;
    event->acceptProposedAction();
  }

 private:
  QWidget* overlay;                 // 透明层部件
  QLabel* overlayLabel;             // 透明层上的标签
  QList<QCPAxisRect*> m_axisRects;  // 存储所有的坐标轴区域
  int m_currentAreaIndex;           // 当前鼠标所在的区域索引

  // 根据鼠标位置获取区域索引
  int getAreaIndex(const QPoint& pos) {
    for (int i = 0; i < m_axisRects.size(); ++i) {
      if (m_axisRects[i]->rect().contains(pos)) {
        return i;
      }
    }
    return -1;
  }

  // 更新透明层位置
  void updateOverlayPosition(const QPoint& pos = QPoint(-1, -1)) {
    int areaIndex = pos.isNull() ? m_currentAreaIndex : getAreaIndex(pos);
    if (areaIndex >= 0 && areaIndex < m_axisRects.size()) {
      m_currentAreaIndex = areaIndex;
      QRect rect = m_axisRects[areaIndex]->rect();
      overlay->setGeometry(rect);
      overlayLabel->setText(QString("在区域 %1 添加曲线").arg(areaIndex + 1));
    }
  }
};

class TreeWidget : public QTreeWidget {
  Q_OBJECT
 public:
  TreeWidget(QWidget* parent = nullptr) : QTreeWidget(parent) {
    setDragEnabled(true);
    setSelectionMode(QAbstractItemView::SingleSelection);
    setHeaderHidden(true);
  }

 protected:
  void startDrag(Qt::DropActions /*supportedActions*/) override {
    if (currentItem()) {
      // 只有叶子节点才允许拖动
      if (currentItem()->childCount() > 0) return;

      QMimeData* mimeData = new QMimeData;
      mimeData->setText(currentItem()->text(0));

      QDrag* drag = new QDrag(this);
      drag->setMimeData(mimeData);

      // 获取节点高度
      int itemHeight = visualItemRect(currentItem()).height();

      // 计算文字宽度
      QFontMetrics fm(font());
      int textWidth = fm.horizontalAdvance(currentItem()->text(0));
      int rectWidth = textWidth * 2;  // 宽度为文字宽度的两倍

      // 创建矩形 pixmap（带透明背景）
      QPixmap pixmap(rectWidth, itemHeight);
      pixmap.fill(Qt::transparent);

      QPainter painter(&pixmap);
      painter.setRenderHint(QPainter::Antialiasing);

      // 设置半透明背景颜色（好看一些，可以自定义颜色）
      // 蓝色，透明度 180/255
      QColor bgColor(100, 180, 255, 180);
      painter.setBrush(QBrush(bgColor));
      // 不画边框
      painter.setPen(Qt::NoPen);
      // 圆角矩形
      painter.drawRoundedRect(0, 0, rectWidth, itemHeight, 5, 5);

      // 绘制文字
      painter.setPen(Qt::white);
      painter.setFont(font());
      painter.drawText(pixmap.rect(), Qt::AlignCenter, currentItem()->text(0));
      painter.end();

      drag->setPixmap(pixmap);
      // 鼠标在矩形中心
      drag->setHotSpot(QPoint(rectWidth / 2, itemHeight / 2));
      drag->exec(Qt::CopyAction);
    }
  }
};

// 创建一个包含3个绘图区域的窗口部件
class MultiPlotWidget : public QWidget {
  Q_OBJECT
 public:
  MultiPlotWidget(QWidget* parent = nullptr) : QWidget(parent) {
    // 创建垂直布局
    QVBoxLayout* layout = new QVBoxLayout(this);
    layout->setContentsMargins(5, 5, 5, 5);

    // 创建一个包含3个区域的PlotWidget
    plot = new PlotWidget;
    layout->addWidget(plot);

    setLayout(layout);
  }

 private:
  PlotWidget* plot;  // 单个包含3个区域的绘图部件
};

int main(int argc, char* argv[]) {
  QApplication a(argc, argv);

  QMainWindow window;

  QSplitter* splitter = new QSplitter;
  TreeWidget* tree = new TreeWidget;
  MultiPlotWidget* multiPlot = new MultiPlotWidget;

  // 填充树数据
  for (int i = 0; i < 5; ++i) {
    QTreeWidgetItem* parent = new QTreeWidgetItem(
        tree, QStringList() << QString("Signal %1").arg(i + 1));
    for (int j = 0; j < 3; ++j) {
      new QTreeWidgetItem(parent, QStringList()
                                      << QString("Channel %1").arg(j + 1));
    }
  }

  splitter->addWidget(tree);
  splitter->addWidget(multiPlot);
  splitter->setStretchFactor(1, 1);

  window.setCentralWidget(splitter);
  window.resize(1000, 800);
  window.setWindowTitle("Multi-Plot Drag & Drop Example");
  window.show();

  return a.exec();
}

#include "main.moc"
